<?php
/**
 * Created by PhpStorm.
 * User: wangjiangtao
 * Date: 2022/6/1
 * Time: 19:28
 */

namespace App\Modules\LuckDraw\Services;


use App\Http\Model\Hint;
use App\Modules\LuckDraw\LuckDraw\LuckDraw;
use App\Modules\LuckDraw\LuckDraw\LuckDrawFactory;
use App\Modules\LuckDraw\Models\AwardPoolModel;
use App\Modules\LuckDraw\Models\DrawManualAwardModel;
use App\Modules\LuckDraw\Models\LuckDrawModel;
use App\Modules\LuckDraw\Strategy\StrategyFactory;
use App\Modules\LuckDraw\UserTag\UserTagFactory;
use Illuminate\Support\Facades\Redis;
use Illuminate\Support\Facades\DB;

class AdminService
{
    protected $table = null;
    protected $poolTable = null;
    protected $luckTable = null;
    public function __construct()
    {
        $this->table = new DrawManualAwardModel();
        $this->poolTable = new AwardPoolModel();
        $this->luckTable = new LuckDrawModel();
    }

    public function addManualAward($luckId,$userId,$awardId,$type,$price = 0){
        $data = [
            'luck_id'   => $luckId,
            'user_id'   => $userId,
            'award_id'  => $awardId,
            'price'     => $price,
            'type'      => $type,
            'timeout'   => date('Y-m-d H;i:s',strtotime('+3 day'))
        ];

        $res = $this->table->addManualAward($data);

        if ($res){
            return true;
        }
        return false;
    }

    public function delManualAward($id){
        $res = $this->table->delManualAward($id);

        if ($res){
            return true;
        }
        return false;
    }


    public function addActivityPool($desc,$luckId){
        $res = $this->poolTable->addActivityPool($desc,$luckId);

        if ($res){
            return true;
        }
        return false;
    }

    public function delActivityPool($id)
    {
        $res = $this->poolTable->delActivityPool($id);
        if (!$res) {
            return false;
        }
        $luckData = $this->luckTable->getActivityInfo(['id']);
        $luckData = array_column($luckData, 'id');

        foreach ($luckData as $luckId){
            $luckDraw = LuckDrawFactory::get($luckId);
            if ($luckDraw == null) {
                continue;
            }

            /**
             * 获取根据用户标签获取抽奖策略 以及 奖池数据
             **/
            $strategyPools = UserTagFactory::get($luckDraw->getLuckId(), 11, $luckDraw->getTag(), $luckDraw->getStrategyPool())->getStrategyAllPool();
            if (empty($strategyPools)) {
                continue;
            }
            //拿出策略名称，奖池id，以及是否是个人的数据
            foreach ($strategyPools as $strategyPool) {
                list($strategyData, $poolId,$userIds) = $strategyPool;
                if($poolId != $id){
                    continue;
                }
                if (empty($strategyData) || empty($poolId)) {
                    continue;
                }
//                $luckDraw->getStrategyPool();
                //根据奖池id 获取奖池数据
                $pool = $luckDraw->getPool($poolId);
                if (!$userIds){
                    $strategy = StrategyFactory::get($luckId, 11, $strategyData, $pool);
                    $strategy->delPoolRedis();
                }else{
                    foreach ($userIds as $userId){
                        $strategy = StrategyFactory::get($luckId, $userId, $strategyData, $pool);
                        $strategy->delPoolRedis();
                    }
                }
            }

        }
        return true;
    }

    public function setActivityPool($id,$pool){

        //过滤 old_data
//        $poolDatas = json_decode($pool,true);
        $poolDatas = $pool;
        $poolNewDatas = [];
        foreach ($poolDatas as $poolDatum){
            unset($poolDatum['old_data']);
            $poolNewDatas[] = $poolDatum;
        }
        $poolNewJson = json_encode($poolNewDatas,JSON_UNESCAPED_UNICODE);
        $res = $this->poolTable->setActivityPool($id,$poolNewJson);
        if (!$res){
            return false;
        }
        $luckData = $this->luckTable->getActivityInfo(['id']);
        $luckData = array_column($luckData,'id');

        foreach ($luckData as $luckId){
            $luckDraw = LuckDraw::instance($luckId);
            if ($luckDraw == null) {
                continue;
            }

            /**
             * 获取根据用户标签获取抽奖策略 以及 奖池数据
             **/
            $strategyPoolData = $luckDraw->getStrategyPool();
            $strategyPools = UserTagFactory::get($luckDraw->getLuckId(), 11, $luckDraw->getTag(), $strategyPoolData)->getStrategyAllPool();
            if (empty($strategyPools)) {
                continue;
            }
            //拿出策略名称，奖池id，以及是否是个人的数据
            foreach ($strategyPools as $strategyPool){
                list($strategyData, $poolId,$userIds,$strategyKey) = $strategyPool;
                $strategyKey = explode('|',$strategyKey);
                if($poolId != $id){
                    continue;
                }
                if (empty($strategyData) || empty($poolId)) {
                    continue;
                }

//                $luckDraw->getStrategyPool();
                //根据奖池id 获取奖池数据
                if (!$userIds){
                    $userIds = [11];
                }
                $pool = $luckDraw->getPool($poolId);
                write_log('ActivityPool','pool',$pool);
                foreach ($userIds as $userId){
                    $strategy = StrategyFactory::get($luckId, $userId, $strategyData, $pool);
                    $upAwardData = $strategy->upAwardStrategy($poolDatas);
                    if ($upAwardData && $upAwardData['status'] == 1 && !empty($upAwardData['ext']) ){
                        write_log('ActivityPool','strategyKey',$strategyKey);
                        write_log('ActivityPool','strategyData更新前',$strategyPoolData);
                        $strategyPoolData = json_decode(json_encode($strategyPoolData,true),JSON_UNESCAPED_UNICODE);
                        if (isset($strategyKey[1])){
                            $strategyPoolData[$strategyKey[0]][$strategyKey[1]]['strategy']['ext'] = $upAwardData['ext']?:new \stdClass();
                        }else{
                            $strategyPoolData[$strategyKey[0]]['strategy']['ext'] = $upAwardData['ext']?:new \stdClass();
                        }
                        write_log('ActivityPool','strategyData更新后',$strategyPoolData);
                        $this->luckTable->setStrategyPool($luckId,json_encode($strategyPoolData,JSON_FORCE_OBJECT));
                    }
                    $strategy->delPoolRedis();
                }

            }

        }
        return true;
    }

    //add by zxiaofee
    public function updateLuckDrawPool($id,$pool){
        //过滤 old_data
        $newPool = [];
        foreach ($pool as $p){
            unset($p['old_data']);
            $newPool[] = $p;
        }

        //更新奖池表 zb_luck_draw_award_pool
        $newPool = json_encode($newPool,JSON_UNESCAPED_UNICODE);
        $res = $this->poolTable->setActivityPool($id,$newPool);
        if ($res == 1){
            //以下开始更新抽奖活动表 zb_luck_draw
            $luckData = $this->luckTable->getActivityInfo(['id']);
            $luckData = array_column($luckData,'id');
            foreach ($luckData as $luckId){
                $luckDraw = LuckDrawFactory::get($luckId);
                if ($luckDraw == null) {
                    continue;
                }

                /**
                 * 获取根据用户标签获取抽奖策略 以及 奖池数据
                 **/

                //更新抽奖活动表的strategy_pool字段
                $result = $luckDraw->updateStrategyPoolByPoolData( $pool);
                if (!$result) {
                    return false;
                }
                //清除奖池缓存信息
                $luckDraw->clearCacheByPoolData($id);
            }
            return true;
        }elseif($res == 0){
            return true;
        }else{
            return false;
        }
    }

    public function delPoolRedis($luckId,$poolId,$strategy,$userList){
        if ($userList){
            foreach ($userList as $userId) {
                $redisKey = sprintf('{LUCKDRAW:STRATEGY:%s:DRAW:%s:POOL:%s:%s}',$strategy, $luckId, $poolId,$userId );
                Redis::del($redisKey);
            }
            return;
        }
        $redisKey = sprintf('{LUCKDRAW:STRATEGY:%s:DRAW:%s:POOL:%s}',$strategy, $luckId, $poolId);
        Redis::del($redisKey);
        return;
    }

    public function upActivityPool($id, $desc, $luckId, $is_open){
        $res = $this->poolTable->upActivityPool($id, $desc, $luckId, $is_open);

        if ($res){
            return true;
        }
        return false;
    }

    //批量更新奖池
    public function updateLuckDrawPools($pools){
        if (empty($pools)) {
            return false;
        }
        try {
            DB::beginTransaction();
            $pools = json_decode($pools,true);

            foreach ($pools as $k=>$pool){
                $ok = $this->updateLuckDrawPool($pool['id'], $pools[$k]['pool']);
                if (!$ok) {
                    DB::rollBack();
                    return false;
                }
            }
            DB::commit();
            write_log("LuckDraw", "updateLuckDrawPools_success",  [$pools]);
            return true;
        } catch (\Exception $e) {
            DB::rollBack();
            write_log("LuckDraw", "updateLuckDrawPools_error",  [$pools, $e->getMessage()]);
            return false;
        }
    }

    // 更新活动
    public function editLuckDraw($params){
        $code = Hint::SUCCESS;
        $msg = Hint::getErrCodeMsg($code);
        $data = [];
        $error = '';

        try {
            if (empty($params)) {
                $code = Hint::PARAM_ERROR;
                $msg = Hint::getErrCodeMsg($code);
                throw new \Exception($msg);
            }
            $luckId = $params['id'] ?? 0;
            if ($luckId<=0){
                $code = Hint::PARAM_ERROR;
                $msg = Hint::getErrCodeMsg($code).',抽奖活动id必需';
                throw new \Exception($msg);
            }
            $data = [];
            if (isset($params['start']) && !empty($params['start'])){
                $data['start'] = $params['start'];
            }
            if (isset($params['end']) && !empty($params['end'])){
                $data['end'] = $params['end'];
            }
            if (empty($data)){
                $code = Hint::PARAM_ERROR;
                $msg = '请输入有效参数';
                throw new \Exception($msg);
            }
            $luckDrawModel = $this->luckTable->getLuckDrawById($luckId);
            if (empty($luckDrawModel)){
                $code = Hint::PARAM_ERROR;
                $msg = '无效抽奖活动';
                throw new \Exception($msg);
            }

            //DB::beginTransaction();
            $res = $this->luckTable->editLuckDraw($luckId, $data);
            if (!$res){
                $code = Hint::PARAM_ERROR;
                $msg = '编辑失败';
                throw new \Exception($msg);
            }

            //DB::commit();
        } catch (\Exception $e) {
            $code = ($code==Hint::SUCCESS) ? Hint::PARAM_ERROR : Hint::ERROR;
            //DB::rollBack();
            $error = $e->getMessage() . ' ' . $e->getFile() . ' ' . $e->getLine();
        }
        write_log("LuckDraw", ($code == Hint::SUCCESS ? '[INFO]':'[ERROR]')." editLuckDraw",  ['params'=>$params, 'msg'=>$msg, 'error'=>$error]);

        return compact('code', 'msg', 'data');
    }

}
